import type { MenuDataItem, UserPermissions } from './typing';
import type { RouteItem } from '@/api/user/login';
import { getUserPermissions } from '@/api/user/login';
import { routes as staticRoutes, default as router } from './index';
import cloneDeep from 'lodash.clonedeep';
import { useWujieStore } from '@/store/wujie';
import { useMicroStore } from '@/store/micro';

// 根级菜单
const rootRouter: MenuDataItem = {
  name: 'index',
  path: '/',
  redirect: '/dashboard',
  meta: {
    title: '首页'
  },
  // eslint-disable-next-line no-underscore-dangle
  component: window.__POWERED_BY_WUJIE__ ? () => import('@/layouts/micro-layout.vue') : () => import('@/layouts/index.vue'),
  children: [] as MenuDataItem[]
};

export const IFRAME_VIEW = 'IframeVIew';
export const ROUTE_VIEW = 'RouteView';
export const defineRouteComponents: Record<string, any> = {
  BasicLayout: () => import('@/layouts/index.vue'),
  PageView: () => import('@/layouts/route-view.vue'),
  [ROUTE_VIEW]: () => import('@/layouts/route-view.vue'),
  [IFRAME_VIEW]: () => import('@/layouts/Iframe-vIew.vue')
};

const defineRouteComponentKeys = Object.keys(defineRouteComponents);

const modules = import.meta.glob('../views/**/*.vue');
const componentMapRouter = {};
// 从树结构解析转换平级结构的路由表
/* eslint-disable max-params */
export const generator = (
  routeMap: RouteItem[],
  menuData: MenuDataItem[],
  routes: MenuDataItem[],
  blankRoutes: MenuDataItem[],
  parentPath?: string
) => {
  routeMap.map((item) => {
    const {
      title,
      hideChildrenInMenu,
      attribute01,
      icon,
      menuMark,
      menuMarkName,
      url,
      siteType,
      microAppSubUrl,
      microAppCode,
      microAppUrl
    } = item.meta || {};
    const target = attribute01 === '_blank' ? '_blank' : null;
    let component = '';
    if (url) {
      component = target !== '_blank' ? IFRAME_VIEW : null;
    } else {
      component = item.component || ROUTE_VIEW;
    }
    let microAppSubComponent = '';
    if (siteType === '1') {
      component = 'avic/micro-app/micropage/MicroPage';
      item.meta.microAppSubComponent = item.component;
      microAppSubComponent = item.component;
    }
    const currentRouter: MenuDataItem = {
      // 如果路由设置了 path，则作为默认 path，否则 路由地址 动态拼接生成如 /dashboard/workplace
      path:
        (item.path ? item.path.substring(0, item.path.indexOf('?') > -1 ? item.path.indexOf('?') : item.path.length) : '') ||
        `${parentPath || ''}/${item.name || item.id}`,
      // path: item.path,
      // 路由名称，建议唯一
      // 路由名称，必须唯一(动态+静态全部唯一)，否则无法按名称跳转路由
      name: `${item.id}`,
      // meta: 页面标题, 菜单图标, 页面权限(供指令权限用，可去掉)
      meta: {
        id: `${item.id}`,
        title,
        icon: icon || null,
        hideInMenu: item.ishidden !== '0',
        hideChildrenInMenu,
        target,
        menuMark,
        menuMarkName,
        url,
        fullPath: item.path,
        microAppSubUrl,
        microAppSubComponent,
        microAppCode,
        microAppUrl
      },
      // 该路由对应页面的 组件 (动态加载 @/views/ 下面的路径文件)
      component:
        component && defineRouteComponentKeys.includes(component) ? defineRouteComponents[component] : modules[`../views/${component}.vue`]
    };
    // 为了防止出现后端返回结果不规范，处理有可能出现拼接出两个 反斜杠
    if (currentRouter.path && !currentRouter.path.startsWith('http')) {
      currentRouter.path = currentRouter.path.replace('//', '/');
    }

    // 重定向
    item.redirect && (currentRouter.redirect = item.redirect);

    // 子菜单，递归处理
    if (item.children?.length > 0) {
      const subMenus: MenuDataItem[] = [];
      generator(item.children, subMenus, routes, blankRoutes, currentRouter.path);
      if (subMenus?.length) {
        if (!item.path) {
          currentRouter.component = defineRouteComponents[ROUTE_VIEW];
          currentRouter.redirect = subMenus[0].path;
        }
        if (target === '_blank') {
          blankRoutes.push(cloneDeep(currentRouter));
        } else {
          if (item.component || url) {
            routes.push(cloneDeep(currentRouter));
          }
        }
        currentRouter.children = subMenus;
      }
    } else {
      if (target === '_blank') {
        blankRoutes.push(currentRouter);
      } else {
        if (item.component || url) {
          routes.push(currentRouter);
        }
      }
    }
    // if (currentRouter.children == null || currentRouter.children?.length <= 0) {
    //   delete currentRouter.children;
    // }
    if (!window.__POWERED_BY_WUJIE__) {
      // 主应用模式
      const microStore = useMicroStore();
      microStore.SET_MICRO_APP(item);
    }
    menuData.push(currentRouter);
    return item;
  });
};

export const generatorDynamicRouter = () =>
  new Promise<UserPermissions>((resolve, reject) => {
    getUserPermissions()
      .then((response) => {
        resolve(generatorRouter(response.data));
      })
      .catch((err) => {
        reject(err);
      });
  });
// 生成子应用的路由
export const generatorMicroRouter = (data) => generatorRouter(data);
const generatorRouter = (data: UserPermissions) => {
  const { menuList, permissionButtonList, denyPermissionColumnList, roleCodeList, userInfo } = data;
  const routes: MenuDataItem[] = [];
  const blankRoutes: MenuDataItem[] = [];
  const menuData: MenuDataItem[] = [];

  // eslint-disable-next-line no-underscore-dangle
  if (window.__POWERED_BY_WUJIE__) {
    generatorMicro(
      menuList.filter((menu) => menu.meta.menuType === '1'),
      menuData,
      routes,
      blankRoutes
    );
  } else {
    generator(
      menuList.filter((menu) => menu.meta.menuType === '1'),
      menuData,
      routes,
      blankRoutes
    );
  }
  // 子应用模式启动
  // eslint-disable-next-line no-underscore-dangle
  if (window.__POWERED_BY_WUJIE__) {
    const wujieStore = useWujieStore();
    // 保存组件地址和路由的映射关系，实现子应用根据组件地址跳转路由
    wujieStore.SET_MAP_ROUTER(componentMapRouter);
  }
  // 主应用模式启动
  // 刷新后重新注册路由子应用动态添加的页签
  if (!window.__POWERED_BY_WUJIE__) {
    const newTabRoutes = generateNewTabRouters();
    routes.push(...newTabRoutes);
  }

  const routerView = {
    path: '/router',
    name: ROUTE_VIEW,
    meta: { title: '路由视图' },
    component: defineRouteComponents[ROUTE_VIEW],
    redirect: '/dashboard',
    children: [...routes]
  };
  rootRouter.children = [...staticRoutes[0].children, routerView];
  return {
    rootRouters: [rootRouter, ...blankRoutes],
    userInfo,
    menuList,
    routes: [...staticRoutes[0].children, ...menuData],
    permissionButtonList,
    denyPermissionColumnList,
    roleCodeList
  } as UserPermissions;
};

// 子应用菜单从树结构解析转换平级结构的路由表
export const generatorMicro = (
  routeMap: RouteItem[],
  menuData: MenuDataItem[],
  routes: MenuDataItem[],
  blankRoutes: MenuDataItem[],
  parentPath?: string
) => {
  routeMap.map((item) => {
    const { title, hideChildrenInMenu, attribute01, icon, menuMark, menuMarkName, url } = item.meta || {};
    const target = attribute01 === '_blank' ? '_blank' : null;
    let component = '';
    if (url) {
      component = target !== '_blank' ? IFRAME_VIEW : null;
    } else {
      component = item.component || ROUTE_VIEW;
    }
    let avicCom = null;
    // 子应用路由名称组合
    component = item.meta.microAppSubComponent || item.component; // 暂时方案后期需要修改
    // eslint-disable-next-line newline-per-chained-call
    const componentId = Math.random().toString(36).substring(2).slice(0, 6);
    const componentName = `microApp${Date.now()}${componentId}`;
    avicCom = createCustomComponent(componentName, component);

    // item.name = componentName;
    const currentRouter: MenuDataItem = {
      // 如果路由设置了 path，则作为默认 path，否则 路由地址 动态拼接生成如 /dashboard/workplace
      path: item.path || `${parentPath || ''}/${item.name || item.id}` || componentName,
      // path: item.path,
      // 路由名称，建议唯一
      // 路由名称，必须唯一(动态+静态全部唯一)，否则无法按名称跳转路由
      name: `${componentName}`,
      // meta: 页面标题, 菜单图标, 页面权限(供指令权限用，可去掉)
      meta: {
        id: `${item.id}`,
        title,
        // eslint-disable-next-line no-undefined
        icon: icon || undefined,
        hideInMenu: item.ishidden !== '0',
        hideChildrenInMenu,
        target,
        menuMark,
        menuMarkName,
        url,
        componentName
      },
      // 该路由对应页面的 组件 (动态加载 @/views/ 下面的路径文件)
      component: avicCom
    };

    // 为了防止出现后端返回结果不规范，处理有可能出现拼接出两个 反斜杠
    if (currentRouter.path && !currentRouter.path.startsWith('http')) {
      currentRouter.path = currentRouter.path.replace('//', '/');
    }
    // 重定向
    item.redirect && (currentRouter.redirect = item.redirect);

    // 子菜单，递归处理
    if (item.children?.length > 0) {
      const subMenus: MenuDataItem[] = [];
      generatorMicro(item.children, subMenus, routes, blankRoutes, currentRouter.path);
      if (subMenus?.length) {
        if (!item.path) {
          currentRouter.component = defineRouteComponents[ROUTE_VIEW];
          currentRouter.redirect = subMenus[0].path;
        }
        if (target === '_blank') {
          blankRoutes.push(cloneDeep(currentRouter));
        } else {
          if (item.component || url) {
            routes.push(cloneDeep(currentRouter));
          }
        }
        currentRouter.children = subMenus;
      }
    } else {
      if (target === '_blank') {
        blankRoutes.push(currentRouter);
      } else {
        if (item.component || url) {
          //  保存组件与路由的映射关系
          componentMapRouter[component] = currentRouter;
          routes.push(currentRouter);
        }
      }
    }
    // if (currentRouter.children === undefined || currentRouter.children.length <= 0) {
    //   delete currentRouter.children;
    // }
    menuData.push(currentRouter);
    return item;
  });
};

/**
 * 注册路由
 * @param { route, url }
 * route: 路由对象
 */
export function addRoute({ route, url }) {
  if (!route?.path) {
    throw new Error('注册路由必须指定path.');
  }
  const meta = { ...route.meta };
  meta.title = meta.title || '新页签';
  // 指定url参数，则默认使用iframe组件跳转
  if (url) {
    if (!route.component) {
      route.component = defineRouteComponents[IFRAME_VIEW];
    }
    meta.url = url;
  }
  route.meta = meta;
  router.addRoute(ROUTE_VIEW, route);
}

/**
 * 动态注册子应用路由
 * @param route 需要注册的路由
 * @param $router 路由实例
 * @param parentRouteName 父路由名称
 */
export function addMicroAppRoute(route, $router, parentRouteName = ROUTE_VIEW) {
  const { path, component, name } = route;
  // eslint-disable-next-line newline-per-chained-call
  const componentId = Math.random().toString(36).substring(2).slice(0, 6);
  // const componentName = `COMP${md5(path)}`;
  const componentName = `microApp${Date.now()}${componentId}`;
  const customComponent = createCustomComponent(componentName, component);
  const routObj = {
    path,
    component: customComponent,
    name: name || componentName,
    meta: {
      ...route.meta
    }
  };
  $router.addRoute(parentRouteName, routObj);
}

/**
 * 将指定组件设置自定义名称
 *
 * @param {String} name 组件自定义名称
 * @param {Component | Promise<Component>} component
 * @return {Component}
 */
export function createCustomComponent(name, component) {
  if (component && defineRouteComponentKeys.includes(component)) {
    return defineRouteComponents[component];
  }
  const comp = modules[`../views/${component}.vue`];
  return {
    name,
    data() {
      return {
        component: null
      };
    },
    template: `<component :is="component"></component>`,
    async created() {
      try {
        const module = await comp();
        this.component = module.default;
      } catch (error) {
        console.error(`can not resolve component ${name}, error:`, error);
      }
    }
  };
}

/**
 * 生成缓存中新页签的路由
 * @param {Array} data 菜单数据
 * @returns Array
 */
export function generateNewTabRouters() {
  const routersList = [];
  const records = window.localStorage.getItem('tabRecords');
  if (records != null) {
    const newTabRecords = JSON.parse(records);
    if (newTabRecords.length > 0) {
      newTabRecords.forEach((item) => {
        const { routerInfo } = item;
        // eslint-disable-next-line newline-per-chained-call
        const componentId = Math.random().toString(36).substring(2).slice(0, 6);
        const component = routerInfo.meta.siteType === 0 ? routerInfo.component : 'avic/micro-app/micropage/MicroPage';
        // eslint-disable-next-line prefer-template
        const menu = {
          path: routerInfo.path,
          name: componentId,
          component: modules[`../views/${component}.vue`],
          meta: {
            ...routerInfo.meta
          }
        };
        if (routerInfo.path) {
          routersList.push(menu);
        }
      });
    }
  }
  return routersList;
}
